package org.altervista.cp.thinjdbc.ds;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import org.altervista.cp.thinbcgen.proxy.Proxy;
import org.altervista.cp.thinbcgen.proxy.ProxyGenerator;
import org.altervista.cp.thinjdbc.wrappers.SQLRuntimeException;

public class DefaultDataSource extends PoolingDataSource {

	public static final int DEFAULT_INITIAL_POOL_SIZE = 0;
	public static final int DEFAULT_MAX_POOL_SIZE = 5;

	public DefaultDataSource(String driver, String url, String username,
			String password, Properties info) {
		super();

		try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			throw new IllegalArgumentException("Driver " + driver
					+ " not found", e);
		}
		_url = url;
		_username = username;
		_password = password;
		_info = info;
	}

	public PrintWriter getLogWriter() {
		return DriverManager.getLogWriter();
	}

	public int getLoginTimeout() {
		return DriverManager.getLoginTimeout();
	}

	public void setLogWriter(PrintWriter out) {
		DriverManager.setLogWriter(out);
	}

	public void setLoginTimeout(int seconds) {
		DriverManager.setLoginTimeout(seconds);
	}

	public boolean isWrapperFor(Class<?> iface) {
		return false;
	}

	public <T> T unwrap(Class<T> iface) {
		return null;
	}

	protected ConnectionPool getConnectionPool() {
		return new ConnectionPool() {

			public _Connection newElement(Object... args) {
				try {
					Connection c = null;
					if (args.length == 2) {
						c = DriverManager.getConnection(_url, (String) args[0],
								(String) args[1]);
					} else {
						if (_info == null) {
							c = DriverManager.getConnection(_url, _username,
									_password);
						} else {
							c = DriverManager.getConnection(_url, _info);
						}
					}
					_Connection _c = (_Connection) proxyGen.generate(c);
					_c._pool = _POOL;
					return _c;
				} catch (SQLException e) {
					throw new IllegalStateException(e);
				}
			}

			protected void shutdown(Connection c) throws SQLException {
				((Connection) ((Proxy) c).unproxy()).close();
			}

		};

	}

	private String _url;
	private String _username;
	private String _password;
	private Properties _info;

	public static abstract class _Connection implements Connection {

		public void close() {
			_pool.release(this);
		}

		private ConnectionPool _pool;
	}

	private static final ProxyGenerator proxyGen = new ProxyGenerator(
			_Connection.class, SQLRuntimeException.EH);

}
